﻿using System;
using System.Collections.Generic;
using MVVM_CAD.Model;

namespace MVVM_CAD.Algorithms
{
    public class BressenhamCircle
    {
        public static IEnumerable<IPoint> GetCircleRepresentation(IPoint initialPoint, IPoint finalPoint)
        {
            var radius = CalculateRadius(initialPoint, finalPoint);
            var returnPoint = new CustomPoint(0, 0);
            var f = 1 - radius;
            var ddFx = 1;
            var ddFy = -2 * radius;
            var x = 0;
            var y = radius;

            returnPoint.X = initialPoint.X;
            returnPoint.Y = initialPoint.Y + radius;
            yield return new CustomPoint(returnPoint.X, returnPoint.Y);
            returnPoint.Y = initialPoint.Y - radius;
            yield return new CustomPoint(returnPoint.X, returnPoint.Y);
            returnPoint.X = initialPoint.X + radius;
            returnPoint.Y = initialPoint.Y;
            yield return new CustomPoint(returnPoint.X, returnPoint.Y);
            returnPoint.X = initialPoint.X - radius;
            yield return new CustomPoint(returnPoint.X, returnPoint.Y);

            while (x < y)
            {
                if (f >= 0)
                {
                    y--;
                    ddFy += 2;
                    f += ddFy;
                }
                x++;
                ddFx += 2;
                f += ddFx;
                returnPoint.X = initialPoint.X + x;
                returnPoint.Y = initialPoint.Y + y;
                yield return new CustomPoint(returnPoint.X, returnPoint.Y);
                returnPoint.X = initialPoint.X - x;
                returnPoint.Y = initialPoint.Y + y;
                yield return new CustomPoint(returnPoint.X, returnPoint.Y);
                returnPoint.X = initialPoint.X + x;
                returnPoint.Y = initialPoint.Y - y;
                yield return new CustomPoint(returnPoint.X, returnPoint.Y);
                returnPoint.X = initialPoint.X - x;
                returnPoint.Y = initialPoint.Y - y;
                yield return new CustomPoint(returnPoint.X, returnPoint.Y);
                returnPoint.X = initialPoint.X + y;
                returnPoint.Y = initialPoint.Y + x;
                yield return new CustomPoint(returnPoint.X, returnPoint.Y);
                returnPoint.X = initialPoint.X - y;
                returnPoint.Y = initialPoint.Y + x;
                yield return new CustomPoint(returnPoint.X, returnPoint.Y);
                returnPoint.X = initialPoint.X + y;
                returnPoint.Y = initialPoint.Y - x;
                yield return new CustomPoint(returnPoint.X, returnPoint.Y);
                returnPoint.X = initialPoint.X - y;
                returnPoint.Y = initialPoint.Y - x;
                yield return new CustomPoint(returnPoint.X, returnPoint.Y);
            }
        }

        private static double CalculateRadius(IPoint initialPoint, IPoint finalPoint)
        {
            var dx = Math.Abs(finalPoint.X - initialPoint.X);
            var dy = Math.Abs(finalPoint.Y - initialPoint.Y);

            return  Math.Round(Math.Sqrt(Math.Pow(dx, 2) + Math.Pow(dy, 2)),2);
        }
    }
}
